package com.example.controller;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.example.dao.ClientInfoDao;
import com.example.dto.BusinessUserDTO;
import com.example.dto.WebchatLoginDTO;
import com.example.dto.WebchatSessionDTO;
import com.example.entity.ClientInfoEntity;
import com.example.exception.BaseException;
import com.example.feign.UsernameFeignClient;
import com.example.model.api.Result;
import com.example.validator.ValidatorUtils;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("webchat")
@Slf4j
public class WebchatController {

    @Autowired
    private Environment environment;

    @Value("${webchat.appid}")
    private String appid;
    @Value("${webchat.secret}")
    private String secret;
    @Value("${webchat.password}")
    private String password;


    @Autowired
    private ClientInfoDao clientInfoDao;
    @Autowired
    private UsernameFeignClient usernameFeignClient;

    @Autowired
    @Qualifier("BusinessUserDetailsServiceImpl")
    private UserDetailsService businessUserDetailsService;

    @Operation(summary = "微信小程序登录", description = "微信小程序登录")
    @PostMapping("login")
    public Result<Map<String, Object>> login(@RequestBody WebchatLoginDTO webchatLoginDTO) {
        //效验数据
        ValidatorUtils.validateEntity(webchatLoginDTO);

        Long tenantId = webchatLoginDTO.getTenantId();
        Long storeId = webchatLoginDTO.getStoreId();
        String code = webchatLoginDTO.getCode();

        // 获取客户端
        List<ClientInfoEntity> clientInfo = clientInfoDao.findClientBusinessInfo(storeId);
        ClientInfoEntity clientInfoEntity = clientInfo.get(0);
        if (Objects.isNull(clientInfoEntity)) {
            throw new BaseException("未找到对应的小程序客户端");
        }

        String clientId = clientInfoEntity.getClientId();
        String clientSecret = clientInfoEntity.getClientSecret();

        // 获取小程序登录凭证
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", appid);
        paramMap.put("secret", secret);
        paramMap.put("js_code", code);
        String result = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session", paramMap);
        WebchatSessionDTO webChatRes = JSONUtil.toBean(result, WebchatSessionDTO.class);
        if (Strings.isNullOrEmpty(webChatRes.getOpenid())) {
            throw new BaseException("小程序登录失败" + webChatRes.getErrmsg());
        }

        // 验证之前的openid是否注册过
        String openid = webChatRes.getOpenid();
        String unionid = webChatRes.getUnionid();
        String sessionKey = webChatRes.getSessionKey();
        Result<BusinessUserDTO> businessUserDTOResult = usernameFeignClient.businessUsernameExist(openid);
        BusinessUserDTO data = businessUserDTOResult.getData();

        if (data == null) {
            BusinessUserDTO businessUserDTO = new BusinessUserDTO();
            businessUserDTO.setOpenid(openid);
            businessUserDTO.setUnionid(unionid);
            businessUserDTO.setSessionKey(sessionKey);
            businessUserDTO.setPassword(password);
            businessUserDTO.setStoreId(storeId);
            businessUserDTO.setTenantId(tenantId);
            Result<String> businessUser = usernameFeignClient.createBusinessUser(businessUserDTO);
            if (businessUser.getCode() != 200) {
                throw new BaseException("新建用户失败");
            }
        }

        // 获取获取自定义token
        HashMap<String, Object> objectHashMap = new HashMap<>();
        objectHashMap.put("grant_type", AuthorizationGrantType.PASSWORD.getValue());
        objectHashMap.put("username", openid);
        objectHashMap.put("password", password);
//        objectHashMap.put("scope", "openid"); // 默认scope为openid 没有 openid userinfo 会报错  "error": "insufficient_scope"
        objectHashMap.put("scope", "message.read");
        String body = HttpRequest.post(environment.getProperty("spring.security.oauth2.resourceserver.jwt.issuer-uri") + "/oauth2/token")
                .basicAuth(clientId, clientSecret)
                .form(objectHashMap)
                .execute().body();

        Map bean = JSONUtil.toBean(body, Map.class);
        bean.put("openid", openid);
        bean.put("session_key", sessionKey);
        bean.put("unionid", unionid);
        return new Result<Map<String, Object>>().ok(bean);
    }
}
